from abc import ABC, abstractmethod
from django.contrib.auth import get_user_model
from django.http import JsonResponse
from django.shortcuts import redirect
from Login.models import ThirdPartyLogin
from utils.JWTTool import jwtTool

User = get_user_model()

class OAuthStrategy(ABC):
    """OAuth策略抽象基类"""
    
    def __init__(self):
        self.platform = self.get_platform_name()
    
    @abstractmethod
    def get_platform_name(self):
        """获取平台名称"""
        pass
    
    @abstractmethod
    def get_authorization_url(self, state=None):
        """获取授权URL"""
        pass
    
    @abstractmethod
    def get_access_token(self, code):
        """获取访问令牌"""
        pass
    
    @abstractmethod
    def get_user_info(self, access_token):
        """获取用户信息"""
        pass
    
    def handle_callback(self, request):
        """处理回调 - 通用实现"""
        code = request.GET.get('code')
        state = request.GET.get('state')
        
        print(f"{self.platform} callback received - code: {code}, state: {state}")
        
        if not code:
            return JsonResponse({'error': '授权失败'}, status=400)
        
        try:
            # 获取访问令牌
            token_data = self.get_access_token(code)
            if not token_data:
                return JsonResponse({'error': '获取访问令牌失败'}, status=400)
            
            access_token = token_data.get('access_token')
            refresh_token = token_data.get('refresh_token')
            expires_in = token_data.get('expires_in')
            
            print(f"Access token: {access_token}")
            
            # 获取用户信息
            user_info = self.get_user_info(access_token)
            if not user_info:
                return JsonResponse({'error': '获取用户信息失败'}, status=400)
            
            print(f"User info: {user_info}")
            
            # 创建或获取用户
            user = self.create_or_get_user(user_info)
            
            # 保存第三方登录信息
            self.save_third_party_login(user, user_info, access_token, refresh_token)
            
            # 生成JWT token
            jwt_token = jwtTool.generate_token(user.id)
            
            # 重定向到前端，携带token
            frontend_url = f"http://localhost:5173/home?token={jwt_token}"
            return redirect(frontend_url)
            
        except Exception as e:
            print(f"Callback error: {e}")
            return JsonResponse({'error': f'登录处理失败: {str(e)}'}, status=500)
    
    def create_or_get_user(self, user_info):
        """创建或获取用户 - 子类可重写"""
        platform_user_id = str(user_info.get('user_id') or user_info.get('id'))
        username = user_info.get('name') or user_info.get('login')
        email = user_info.get('email')
        
        user, created = User.objects.get_or_create(
            username=f"{self.platform}_{platform_user_id}",
            defaults={
                'email': email or f"{platform_user_id}@{self.platform}.com",
                'first_name': username or '',
            }
        )
        return user
    
    def save_third_party_login(self, user, user_info, access_token, refresh_token):
        """保存第三方登录信息"""
        platform_user_id = str(user_info.get('user_id') or user_info.get('id'))
        
        third_party_login, _ = ThirdPartyLogin.objects.get_or_create(
            platform=self.platform,
            platform_user_id=platform_user_id,
            defaults={
                'user': user,
                'access_token': access_token,
                'refresh_token': refresh_token,
                'platform_user_info': user_info
            }
        )
        return third_party_login
